Post not yet marked as solved
Hello,
I am trying to get network statistics using Swift on macOS. I am attempting to obtain:
total input bytes
total output bytes
total input packets
total output packets
The following code works in the app as far as I can tell so far, but... the for-loop is a hack that I'd like to correct by properly iterating over all the interfaces.
import Foundation
import OSLog
struct NetworkStatisticsData {
var totalInputBytes: UInt64 = 0
var totalOutputBytes: UInt64 = 0
var totalInputPackets: UInt64 = 0
var totalOutputPackets: UInt64 = 0
}
final class NetworkStatistics: Sendable {
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!,
category: "SwiftNetworkInformation")
func getNetworkStatistics() -> NetworkStatisticsData {
var networkStatisticsData = NetworkStatisticsData()
for i in 1..<24 { // <- this for-loop should be iterating over a list of interfaces. NET_RT_IFLIST2 ?
var keys: [Int32] = [ CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, Int32(i), IFDATA_GENERAL ]
var mibData: ifmibdata = ifmibdata()
var mibDataSize: size_t = MemoryLayout<ifmibdata>.size
if sysctl(&keys, u_int(keys.count), &mibData, &mibDataSize, nil, 0) < 0 {
logger.error("sysctl error getting mib data: \(String(describing: strerror(errno)))")
}
networkStatisticsData.totalInputPackets += mibData.ifmd_data.ifi_ipackets
networkStatisticsData.totalOutputPackets += mibData.ifmd_data.ifi_opackets
networkStatisticsData.totalInputBytes += mibData.ifmd_data.ifi_ibytes
networkStatisticsData.totalOutputBytes += mibData.ifmd_data.ifi_obytes
}
return networkStatisticsData
}
}
Any thoughts on how to iterate over all of the network interfaces (maybe using NET_RT_IFLIST2)? When I run ifconfig in the terminal, there are 24 interfaces, hence the reason for 24 in the for-loop.
Post not yet marked as solved
As TN3135 clearly explains the limitations apple puts on the low level networking, it doesn’t really give a reason. Presumably the power consumption problem. But as the battery technology continues evolving, it could be exciting that apple might loose the restrictions someday. The watch itself is powerful enough to do a lot of sophisticated works, sure it works best with companion apps on iPhone, but even as a standalone device, we can still provide many advanced user experience with low level networking supports.
wish apple guys can read it and give a consideration.
Post not yet marked as solved
Is it possible to develop two apps in which one should use cellular data only and another one should connect with Wi-Fi socket for data communication?
Post not yet marked as solved
This was mentioned in another thread 4 years ago:
This whole discussion assumes that every network connection requires a socket. This isn’t the case on most Apple platforms, which have a user-space networking stack that you can access via the Network framework [1].
[1] The one exception here is macOS, where Network framework has to run through the kernel in order to support NKEs. This is one of the reasons we’re in the process of phasing out NKE support, starting with their deprecation in the macOS 10.15 SDK.
Is macOS still an unfortunate exception that requires a socket per Network framework's connection?
Post not yet marked as solved
I've been investigating an issue with the SO_OOBINLINE socket option. When that option is disabled, the expectation is that out-of-band data that is sent on the socket will not be available through the use of read() or recv() calls on that socket.
What we have been noticing is that when the socket is bound to a non-loopback address (and the communication is happening over that non-loopback address), then even when SO_OOBINLINE is disabled for the socket, the read()/recv() calls both return the out-of-band data. The issue however isn't reproducible with loopback address, and read()/recv() both correctly exclude the out-of-band data.
This issue is only noticed on macos. I have been able to reproduce on macos M1, following version, but the original report which prompted me to look into this was reported on macos x64. My M1 OS version is:
sw_vers
ProductName: macOS
ProductVersion: 14.3.1
BuildVersion: 23D60
Attached is a reproducer (main.c.txt - rename it to main.c after downloading) that I have been able to develop which reproduces this issue on macos. When you compile and run that:
./a.out
it binds to a non-loopback address by default and you should see the failure log, resembling:
...
ERROR: expected: 1234512345 but received: 12345U12345
To run the same reproducer against loopback address, run it as:
./a.out loopback
and that should succeed (i.e. no out-of-band data) with logs resembling:
...
SUCCESS: completed successfully, expected: 1234512345, received: 1234512345
Is this a bug in the OS? I would have reported this directly through feedback assistant, but my past few open issues (since more than a year) have not even seen an acknowledgement or a reply, so I decided to check here first.
main.c.txt
Initially, my task was to determine which type of connection is being used at the moment: 5G or 4G. And I found "CTTelephonyNetworkInfo().serviceCurrentRadioAccessTechnology" but there is a problem when the device has more than one sim.
My iPhone has two sims, one physical and one electronic.
I need to determine which one is used to access the network. I tried to use "CTTelephonyNetworkInfo().serviceCurrentRadioAccessTechnology" but it is a dictionary [String: String] that only indicates the connection of each of the cards, and it is not possible to find out which one is active from this dictionary. So how can I determine which of the two cards are currently being used to access the Internet?
Post not yet marked as solved
Hi I'm getting this issue:
Crashed: com.apple.network.connections
0 libsystem_kernel.dylib 0xa974 __pthread_kill + 8
1 libsystem_pthread.dylib 0x60ec pthread_kill + 268
2 libsystem_c.dylib 0x75b80 abort + 180
3 libsystem_malloc.dylib 0x2bc68 malloc_vreport + 896
4 libsystem_malloc.dylib 0x2bf10 malloc_zone_error + 104
5 libsystem_malloc.dylib 0x21a44 nanov2_guard_corruption_detected + 44
6 libsystem_malloc.dylib 0x7f84 nanov2_find_block_and_allocate + 402
7 libc++abi.dylib 0x16b84 operator new(unsigned long) + 52
8 Network 0x7e8c void std::__1::vector<nw_object_wrapper_t, std::__1::allocator<nw_object_wrapper_t> >::__emplace_back_slow_path<nw_object*&>(nw_object*&) + 124
9 Network 0x7dd8 nw_array_append + 280
10 Network 0xc3d0 __nw_resolver_insert_endpoint_locked_block_invoke + 1036
11 Network 0xbd80 nw_array_apply + 124
12 Network 0x77250 nw_resolver_insert_endpoint_locked + 256
13 Network 0x770b8 nw_resolver_insert_address + 1356
14 Network 0x29a850 __nw_resolver_create_dns_getaddrinfo_locked_block_invoke.187 + 7836
15 libdns_services.dylib 0x1000 ___dnssd_getaddrinfo_activate_block_invoke + 216
16 libdispatch.dylib 0x3dd4 _dispatch_client_callout + 20
17 libdispatch.dylib 0x72d8 _dispatch_continuation_pop + 600
18 libdispatch.dylib 0x1b1c8 _dispatch_source_latch_and_call + 420
19 libdispatch.dylib 0x19d8c _dispatch_source_invoke + 832
20 libdispatch.dylib 0xd284 _dispatch_workloop_invoke + 1756
21 libdispatch.dylib 0x16cb4 _dispatch_root_queue_drain_deferred_wlh + 288
22 libdispatch.dylib 0x16528 _dispatch_workloop_worker_thread + 404
23 libsystem_pthread.dylib 0x1f20 _pthread_wqthread + 288
24 libsystem_pthread.dylib 0x1fc0 start_wqthread + 8
Post not yet marked as solved
I need to obtain data through mqtt and subscription? Is there any idea or framework ?
Think you
Hey everyone,
I'm tackling a scenario where I need to fetch a comprehensive list of both IPv4 and IPv6 addresses linked to a particular DNS. I know about the POSIX function getaddrinfo(), but I'm on the lookout for an asynchronous solution. Previously, I could've used CFHost, but unfortunately, it's been deprecated. Any suggestions or insights on how to achieve this asynchronously would be greatly appreciated!
Thanks,
Harshal
Post not yet marked as solved
Hello,
I've been encountering some challenges while working with NWConnectionGroup and NWMulticastGroup for multicast operations on iOS. I have a few doubts and issues that I would like to address:
1. NWMulticastGroup Initialization
It seems that when initializing NWMulticastGroup, only one NWEndpoint can be passed, and attempting to pass multiple endpoints results in failure. Can someone confirm if this behavior is correct?
2. Interface Level Control
Upon initializing NWConnectionGroup, it appears that packets are received on all interfaces without the ability to control this at the interface level. Is this correct? If not is there a way to configure NWConnectionGroup to receive packets on all interfaces?
3. Sending Behavior
During the send operation, it appears that the data is sent through any one of the available interfaces, and there doesn't seem to be an option to configure it to send through all available endpoints. Is there a way to enable sending data through all available endpoints?
Any insights, guidance, or solutions to these issues would be greatly appreciated. Has anyone else encountered similar problems or found workarounds for these limitations?
Thank you for your assistance and support.
Thanks,
Harshal
Post not yet marked as solved
I would like to determine why communication with the server is failing.
The following situation.
・An SSL error occurs when communicating with the server.
ATS failed system trust
Connection 13: system TLS Trust evaluation failed(-9802)
Connection 13: TLS Trust encountered error 3:-9802
Connection 13: encountered error(3:-9802)
nw_connection_copy_connected_local_endpoint_block_invoke [C14] Client called nw_connection_copy_connected_local_endpoint on unconnected nw_connection
nw_connection_copy_connected_remote_endpoint_block_invoke [C14] Client called nw_connection_copy_connected_remote_endpoint on unconnected nw_connection
nw_connection_copy_protocol_metadata_internal_block_invoke [C14] Client called nw_connection_copy_protocol_metadata_internal on unconnected nw_connection
Task <07B896CB-44B4-44BC-87B4-EB786D5B25DA>.<10> HTTP load failed, 0/0 bytes (error code: -1200 [3:-9802])
Task <07B896CB-44B4-44BC-87B4-EB786D5B25DA>.<10> finished with error [-1200] Error Domain=NSURLErrorDomain Code=-1200 "SSLエラーが起きたため、サーバへのセキュリティ保護された接続を確立できません。" UserInfo={NSLocalizedRecoverySuggestion=それでもサーバに接続しますか?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x1091bca00) s: Default Company Ltd i: Default Company Ltd>"
), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://xxxx, NSErrorFailingURLStringKey=https://xxxx, NSUnderlyingError=0x2838e96e0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x28073aa80>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x1091bca00) s: Default Company Ltd i: Default Company Ltd>"
)}}, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <07B896CB-44B4-44BC-87B4-EB786D5B25DA>.<10>"
), _kCFStreamErrorCodeKey=-9802, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <07B896CB-44B4-44BC-87B4-EB786D5B25DA>.<10>, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x28073aa80>, NSLocalizedDescription=SSLエラーが起きたため、サーバへのセキュリティ保護された接続を確立できません。}
・I checked that server for ATS (App Transport Security) support with the nscurl command and found that it supported it without any problems.
・The error content changes when an ATS exception is handled by the iOS client.
Connection 35: default TLS Trust evaluation failed(-9807)
Connection 35: TLS Trust encountered error 3:-9807
Connection 35: encountered error(3:-9807)
nw_connection_copy_connected_local_endpoint_block_invoke [C36] Client called nw_connection_copy_connected_local_endpoint on unconnected nw_connection
nw_connection_copy_connected_remote_endpoint_block_invoke [C36] Client called nw_connection_copy_connected_remote_endpoint on unconnected nw_connection
nw_connection_copy_protocol_metadata_internal_block_invoke [C36] Client called nw_connection_copy_protocol_metadata_internal on unconnected nw_connection
Task <882E38EE-4E0D-4428-A4BE-709BB8448530>.<34> HTTP load failed, 0/0 bytes (error code: -1202 [3:-9807])
Task <882E38EE-4E0D-4428-A4BE-709BB8448530>.<34> finished with error [-1202] Error Domain=NSURLErrorDomain Code=-1202 "このサーバの証明書は無効です。"xxxx"に偽装したサーバに接続している可能性があり、機密情報が漏えいするおそれがあります。" UserInfo={NSLocalizedRecoverySuggestion=それでもサーバに接続しますか?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x14c2e9000) s: Default Company Ltd i: Default Company Ltd>"
), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://xxxx, NSErrorFailingURLStringKey=https://xxxx, NSUnderlyingError=0x281d86310 {Error Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x2823f7200>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9807, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9807, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x14c2e9000) s: Default Company Ltd i: Default Company Ltd>"
)}}, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <882E38EE-4E0D-4428-A4BE-709BB8448530>.<34>"
), _kCFStreamErrorCodeKey=-9807, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <882E38EE-4E0D-4428-A4BE-709BB8448530>.<34>, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x2823f7200>, NSLocalizedDescription=このサーバの証明書は無効です。"xxxx"に偽装したサーバに接続している可能性があり、機密情報が漏えいするおそれがあります。}
・Client can communicate normally when client is not iOS (also Safari)
・Even on iOS, after many failed attempts, the communication suddenly succeeds (after success, the session cache is consulted).
The server appears to be fine, but that said, iOS is failing to communicate.
What are possible cases like this?
Post not yet marked as solved
I'm trying to use rvictl but here's what I run into
> rvictl
Could not get list of devices
> sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.rpmuxd.plist
Load failed: 5: Input/output error
Try running `launchctl bootstrap` as root for richer errors.
> ls /System/Library/LaunchDaemons/com.apple.rpmuxd.plist
ls: /System/Library/LaunchDaemons/com.apple.rpmuxd.plist: No such file or directory
XCode version 15.3
MacOS Sonoma 14.4.1
Apple M1 Max
Post not yet marked as solved
Hello,
I'm looking for a way to detect using NWPathMonitor when the iOS device is connected to a router but not to the internet.
As an example a mobile router WiFi without SIM.
In settings I'm able to switch the connection to its WiFi, once connected a label below the SSID shows Not connected to the internet.
I would like to show the same thing to the user inside my app, but unfortunately I always get the satisfied answer.
Am I missing something in configuring NWPathMonitor or reading the answer?
final class InternetConnectionMonitor {
lazy var internetConnectionStatusPublisher: AnyPublisher<InternetConnectionStatus, Never> = {
_internetConnectionStatusSubject
.compactMap{ $0 }
.eraseToAnyPublisher()
}()
var lastInternetConnectionStatus: InternetConnectionStatus? {
_internetConnectionStatusSubject.value
}
private let _internetConnectionStatusSubject = CurrentValueSubject<InternetConnectionStatus?, Never>(nil)
private let pathMonitor = NWPathMonitor()
private let pathMonitorQueue = DispatchQueue(label: "com.xxxxx-network-monitor", qos: .default)
init() {
startPathMonitoring()
}
private func startPathMonitoring() {
pathMonitor.pathUpdateHandler = { [weak self] path in
guard let self else { return }
let networkStatus = InternetConnectionStatus(from: path)
self._internetConnectionStatusSubject.send(networkStatus)
}
pathMonitor.start(queue: pathMonitorQueue)
}
}
Post not yet marked as solved
Users have reported unusually high data usage with my app.
So to investigate I have profiled in instruments. My app as expected in using minimal data. However in instruments I see an "Unknown" process. Which sends around 1mb of data every 2 seconds.
Can anyone explain what unknown process is? Sorry my question is vague but I'm at the beginning of understanding the instruments outputs so your help is so very much appreciated.
Post not yet marked as solved
We've released our app on the App Store and are facing the following issue: Some users are unable to connect to the server with the app, and the "Cellular Data" settings for our app are missing in the system settings.
The app is developer on Qt framework (qt.io)
This is how it should be
This is what some users reporting - app unable to make requests to the server by https (request timeout)
Why it happening?
Any tips how to fix?
Post not yet marked as solved
Hi,
I observed some unexpected behavior and hope that someone can enlighten me as to what this is about:
mDNSResponder prepends IP / network based default search domains that are checked before any other search domain. E.g. 0.1.168.192.in-addr.arpa. would be used for an interface with an address in the the 192.168.1.0/24 subnet. This is done for any configured non-link-local IP address.
I tried to find any mention of an approach like this in RFCs but couldn't spot anything.
Please note that this is indeed a search domain and different from reverse-DNS lookups.
Example output of tcpdump for ping devtest:
10:02:13.850802 IP (tos 0x0, ttl 64, id 43461, offset 0, flags [none], proto UDP (17), length 92)
192.168.1.2.52319 > 192.168.1.1.53: 54890+ [1au] A? devtest.0.1.168.192.in-addr.arpa. (64)
I was able to identify the code that adds those default IP subnet based search domains but failed to spot any indication as to what this is about: https://github.com/apple-oss-distributions/mDNSResponder/blob/d5029b5/mDNSMacOSX/mDNSMacOSX.c#L4171-L4211
Does anyone here have an ideas as to what this might be about?
Post not yet marked as solved
The man page for getifaddrs states:
The ifa_data field references address family specific data. For AF_LINK addresses it
contains a pointer to the struct if_data (as defined in include file <net/if.h>) which
contains various interface attributes and statistics. For all other address families, it
contains a pointer to the struct ifa_data (as defined in include file <net/if.h>) which
contains per-address interface statistics.
I assume that "AF_LINK address" is the one that has AF_LINK in the p.ifa_addr.sa_family field.
However I do not see "struct ifa_data" anywehere. Is this a documentation bug and if so how do I read this documentation right?
Post not yet marked as solved
Hello! I'm playing around with QUIC and Swift and using the Network framework. So far, the process has been really straightforward, but I noticed that I can't seem to get a handle on the stream with identifier 0.
If I use NWConnection directly, I only have access to the first stream, which has the stream ID 0. This not what I want since I wanna use multiple streams. Following the documentation, I started using NWMultiplexGroup and starting a NWConnectionGroup with it.
Everything works fine and I can get all streams that my backend service opens using NWMultiplexGroup's newConnectionHandler property. However, whenever backend sends a message on stream_id 0, none of my connections receive it. Looking around with
connection.metadata(definition: NWProtocolQUIC.definition) as? NWProtocolQUIC.Metadata
for each connection, I see that all streams are accounted for except stream 0. Then, using the NWConnectionGroup variant of the above
connectionGroup.metadata(definition: NWProtocolQUIC.definition) as? NWProtocolQUIC.Metadata
I see that the connection group itself has Stream ID 0. However, calling setReceiveHandler does nothing (it's never called, even when backend is sending messages) and when I attempt to send a message using NWConnectionGroup's -send method, a new stream is opened (instead of it being sent on stream ID 0).
How can one get a handle on NWConnection for stream ID 0?
Post not yet marked as solved
We are using and iOS version 17.4.1 and 17.5(beta) , and when are we facing the issue for local network permission in our app.
Success scenario steps:
Don't allow the local network permission in our App
Allow it manually in app setting for local network permission(works only in first install of the App)
We are able to call the API successfully
Error scenario steps:
Allow the local network permission popup to app when asked for permission
Call the API successfully
Uninstall the app and install the same app again and don't allow the local network permission
API call fail's
Manually change the local network permission to allow in app settings
Still the API call fails even if we allow the local network permission
Conclusion : We are getting API error when re-install the app and if it is not allowed local network permission as well as when we allow the local network permission. Looks like caching issue.
Note: Even if uninstall and install multiple time and allow the local network permission from 2nd time onward API keeps on failing , but these scenario work perfectly fine on iOS 16 version and below. Even the existing app stopped working after updating iOS version to 17 and above.
Also we found alternatively when we uninstall the app and restart the device and install it back again it works fine for the first time as a fresh install.
Additionally : We are not calling local network permission explicitly, when the API call is happening this is native popup coming on iOS
Post not yet marked as solved
Most apps perform ordinary network operations, like fetching an HTTP resource with URLSession and opening a TCP connection to a mail server with Network framework. These operations are not without their challenges, but they’re the well-trodden path.
Note If your app performs ordinary networking, see TN3151 Choosing the right networking API for recommendations as to where to start.
Some apps have extra-ordinary networking requirements. For example, apps that:
Help the user configure a Wi-Fi accessory
Require a connection to run over a specific interface
Listen for incoming connections
Building such an app is tricky because:
Networking is hard in general.
Apple devices support very dynamic networking, and your app has to work well in whatever environment it’s running in.
Documentation for the APIs you need is tucked away in man pages and doc comments.
In many cases you have to assemble these APIs in creative ways.
If you’re developing an app with extra-ordinary networking requirements, this post is for you.
Note If you have questions or comments about any of the topics discussed here, put them in a new thread here on DevForums. Make sure I see it by tagging it with… well… tags appropriate to the specific technology you’re using, like Foundation, CFNetwork, Network, or Network Extension.
Links, Links, and More Links
Each topic is covered in a separate post:
The iOS Wi-Fi Lifecycle describes how iOS joins and leaves Wi-Fi networks. Understanding this is especially important if you’re building an app that works with a Wi-Fi accessory.
Network Interface Concepts explains how Apple platforms manage network interfaces. If you’ve got this far, you definitely want to read this.
Network Interface Techniques offers a high-level overview of some of the more common techniques you need when working with network interfaces.
Network Interface APIs describes APIs and core techniques for working with network interfaces. It’s referenced by many other posts.
Running an HTTP Request over WWAN explains why most apps should not force an HTTP request to run over WWAN, what they should do instead, and what to do if you really need that behaviour.
If you’re building an iOS app with an embedded network server, see Showing Connection Information in an iOS Server for details on how to get the information to show to your user so they can connect to your server.
Many folks run into trouble when they try to find the device’s IP address, or other seemingly simple things, like the name of the Wi-Fi interface. Don’t Try to Get the Device’s IP Address explains why these problems are hard, and offers alternative approaches that function correctly in all network environments.
If you’re building an app that works with a Wi-Fi accessory, see Working with a Wi-Fi Accessory.
If you’re trying to gather network interface statistics, see Network Interface Statistics.
There are also some posts that are not part of this series but likely to be of interest if you’re working in this space:
Local Network Privacy FAQ discusses iOS’s local network privacy feature.
Calling BSD Sockets from Swift does what it says on the tin, that is, explain how to call BSD Sockets from Swift. When doing weird things with the network, you often find yourself having to use BSD Sockets, and that API is not easy to call from Swift. The code therein is primarily for the benefit of test projects, oh, and DevForums posts like this one.
TN3111 iOS Wi-Fi API overview is a critical resource if you’re doing Wi-Fi specific stuff on iOS.
TLS For Accessory Developers tackles the tricky topic of how to communicate securely with a network-based accessory.
Networking Resources has links to many other useful resources.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Revision History
2024-04-30 Added a link to Network Interface Statistics.
2023-09-14 Added a link to TLS For Accessory Developers.
2023-07-23 First posted.